﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.IO.IsolatedStorage;
using log4net;

namespace Entangle
{
    [Serializable]
    public class Configuration
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Configuration));

        #region Singleton
        private Configuration()
        {
            log.Debug("Creating Configuration instance.");
        }


        private static Configuration _instance;

        private static Configuration GetInstance()
        {
            if (_instance == null)
            {
                _instance = new Configuration();
                Load();
            }

            return _instance;
        }
        public static Configuration Instance
        {
            get { return GetInstance(); }
        }
        #endregion
        private static void Load()
        {
            log.Info("Loading config from file...");
            try
            {
                IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null);
                string[] fileNames = isoStore.GetFileNames(Properties.Settings.Default.ConfigFileName);
                if (fileNames.Length == 0)
                {
                    log.Info("Config file not found, configuration will not be loaded.");
                    _instance.config = new SerialConfiguration();
                }
                else
                {
                    XmlSerializer xs = new XmlSerializer(new SerialConfiguration().GetType());
                    StreamReader reader = new StreamReader(new IsolatedStorageFileStream(Properties.Settings.Default.ConfigFileName, FileMode.Open, isoStore));
                    _instance.config = (SerialConfiguration)xs.Deserialize(reader);
                    reader.Close();

                    log.Info("Config loaded successfuly.");
                }
            }
            catch (Exception ex)
            {
                log.Error("Exception while creating Configuration instance!");
                log.Error(ex.Message);
                log.Error(ex.StackTrace);
                throw new Exception("Critical error in Configuration", ex);
            }
        }
        private static void Save()
        {
            XmlSerializer xs = new XmlSerializer(Configuration.GetInstance().config.GetType());

            log.Debug("Obtaining isolated storage.");
            IsolatedStorageFile isoStore = IsolatedStorageFile.GetStore(IsolatedStorageScope.User | IsolatedStorageScope.Assembly | IsolatedStorageScope.Domain, null, null);

            log.Debug("Writing configuration file");
            StreamWriter writer = new StreamWriter(new IsolatedStorageFileStream(Properties.Settings.Default.ConfigFileName, FileMode.Create, isoStore));
            xs.Serialize(writer, GetInstance().config);
            writer.Flush();
            writer.Close();
        }

        #region SerialConfiguration
        public class SerialConfiguration
        {
            public int prvUserId;
            public string lastKnownPartnerIP;
            public SynchStatus synchStatus = SynchStatus.Unknown;
            public string synchServer = String.Empty;
            public string currentAESKeyID = String.Empty;
            public DateTime lastPartnerContact;
            public bool askOnExit = true;
        }
        #endregion
        private SerialConfiguration config;

        public static int UserID
        {
            get { return Instance.config.prvUserId; }
            set
            {
                Instance.config.prvUserId = value;
                Save();
            }
        }

        public static SynchStatus SynchStatus
        {
            get { return Instance.config.synchStatus; }
            set
            {
                Instance.config.synchStatus = value;
                Save();
            }
        }
        public static string lastKnownPartnerIP
        {
            get { return Instance.config.lastKnownPartnerIP; }
            set
            {
                Instance.config.lastKnownPartnerIP = value;
                Save();
            }
        }

        public static string SynchServer
        {
            get { return Instance.config.synchServer; }
            set
            {
                Instance.config.synchServer = value;
                Save();
            }
        }

        public static string CurrentAESKeyID
        {
            get { return Instance.config.currentAESKeyID; }
            set
            {
                Instance.config.currentAESKeyID = value;
                Save();
            }
        }

        public static DateTime LastPartnerContact
        {
            get { return Instance.config.lastPartnerContact; }
            set
            {
                Instance.config.lastPartnerContact = value;
                Save();
            }
        }
        public static bool AskOnExit
        {
            get { return Instance.config.askOnExit; }
            set
            {
                Instance.config.askOnExit = value;
                Save();
            }
        } 
    }
}
